package kr.co.goodwilldd.framework.validators;

import java.util.Locale;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import kr.co.goodwilldd.framework.annotations.FieldMatch;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

public class FieldMatchValidator implements
		ConstraintValidator<FieldMatch, Object> {
	private String firstFieldName;
	private String firstDescription;
	private String secondFieldName;
	private String secondDescription;

	@Override
	public void initialize(final FieldMatch constraintAnnotation) {
		firstFieldName = constraintAnnotation.first();
		secondFieldName = constraintAnnotation.second();
		firstDescription = constraintAnnotation.firstDesc();
		secondDescription = constraintAnnotation.secondDesc();
	}

	@Autowired
	ReloadableResourceBundleMessageSource validationMessageSource;

	@Override
	public boolean isValid(final Object value,
			final ConstraintValidatorContext context) {
		boolean matches = true;
		try {
			final Object firstObj = BeanUtils
					.getProperty(value, firstFieldName);
			final Object secondObj = BeanUtils.getProperty(value,
					secondFieldName);

			boolean tempMatches = (firstObj != null)
					&& firstObj.equals(secondObj);

			if (!tempMatches) {
				String messages = validationMessageSource.getMessage(
						"kr.co.insoft.field.match.message", new Object[] {
								firstDescription, secondDescription },
						Locale.getDefault());
				addConstraintViolation(context, messages, firstFieldName);
			}

			matches = matches ? tempMatches : matches;
		} catch (final Exception ignore) {
			// ignore
		}
		return matches;
	}

	private void addConstraintViolation(ConstraintValidatorContext context,
			String message, String field) {
		context.disableDefaultConstraintViolation();
		context.buildConstraintViolationWithTemplate(message).addNode(field)
				.addConstraintViolation();
	}
}
